home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 23 / AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso / PublicDomain / Anwendungen / db3.6-beta-src / DESIGN.C < prev    next >
C/C++ Source or Header  |  1997-11-25  |  52KB  |  1,512 lines

  1.  
  2. #include <exec/types.h>
  3. #include <intuition/intuition.h>
  4. #include <libraries/gadtools.h>
  5. #include <proto/intuition.h>
  6. #include <proto/graphics.h>
  7. #include <proto/gadtools.h>
  8. #include <proto/utility.h>
  9. #include <proto/exec.h>                 /* CopyMem() */
  10. #include <string.h>             /* strcpy */
  11. #include <stdlib.h>     /* abs() macro */
  12.  
  13. #include "Design.h"
  14. #include "dbGUI.h"
  15. #include "dbparser.h"
  16. #include "Toolbox.h"
  17. #include "DesignGUI.h"
  18. #include "Version.h"
  19.  
  20. #include "Pointers.h"
  21.  
  22. #include <stdio.h> // Diagnostics
  23.  
  24. /*
  25.  * Externs to make the new GadToolsBox interface work
  26.  * Remove "static" from these in DesignGUI.c
  27.  */
  28. extern struct Gadget         *VisGadgets[];
  29. extern struct Window         *VisWnd;
  30. extern struct NewMenu                   DesignNewMenu[];
  31. extern struct Menu           *DesignMenus;
  32.  
  33. #define CURSORWIDTH 3
  34. #define DRAGTRESHOLD 6
  35. #define TOGGLE_LED *(UBYTE *)0xbfe001 ^= 2      /* Debug */
  36.  
  37. /* Handy macros */
  38. #define FLOOR(x,f) if ((x)<(f)) (x) = (f) 
  39.  
  40. /* Return codes from GadToolBox handlers */
  41. #define RET_OK 1
  42. #define RET_CANCEL 2
  43.  
  44.  
  45.  
  46. extern WORD LastLeftEdge;
  47. extern WORD LastTopEdge;                /* For nice layoutswitching */
  48.  
  49. extern void UpdateWindow(struct Pro *Pr);
  50. extern void UpdateDragBar(struct Pro *Pr);
  51.  
  52. typedef int Bool;       /* A char would be smaller, but will produce non-cast warnings */
  53.  
  54. typedef struct {
  55.         struct VisFldInfo *vf;
  56.         Bool after;     /* Has cursor passed field? (to the left or right of field) */
  57. } Cursor;
  58.  
  59.  
  60. struct EasyStruct ES_ViewDesignHelp =
  61. {
  62.         sizeof(struct EasyStruct),
  63.         0,
  64.         (STRPTR)"View design",
  65.         (STRPTR)"%s",
  66.         (STRPTR)"Ok"
  67. };
  68.  
  69.  
  70. /**********************************************************************/
  71. /*                              Globals                               */
  72. /**********************************************************************/
  73.  
  74. Cursor Crsr;
  75. struct VisFldInfo *Selected;    /* The selected field that has a rubberband */
  76. int DragCnt = 0;        /* Non-zero if dragging Selected. */
  77. Bool Sizing = FALSE;
  78.  
  79. struct Window *ToolBox = NULL;
  80.  
  81. /* GadToolBox handlers uses global variables */
  82. extern struct Pro *CurrentPro;
  83. struct VisFldInfo *Vf;
  84. extern char *RFFTagNames[];
  85.  
  86. /* The clipboard */
  87. struct VisFldInfo *Clip = NULL;
  88.  
  89. /**********************************************************************/
  90. /*                         Support functions                          */
  91. /**********************************************************************/
  92.  
  93. struct VisFldInfo *PrevVisFldInfo(struct Layout *Lay, struct VisFldInfo *vf)
  94. {
  95.         struct VisFldInfo *t = Lay->FirstVisFldInfo;
  96.         if (t == vf) return NULL;
  97.         for (; t; t = t->Next) if (t->Next == vf) return t;
  98.         return NULL; /* Safety */
  99. }
  100.  
  101. static void InitCursor(struct Layout *Lay, Cursor *crsr)
  102. {
  103.         crsr->vf = Lay->FirstVisFldInfo;
  104.         crsr->after = FALSE;
  105. }
  106.  
  107. static void GetCursorPosition(Cursor *crsr, WORD *x, WORD *y)
  108. {
  109.         /* Return position of cursor in (x,y) coords */
  110.         if (crsr->vf) {
  111.                 *y = crsr->vf->Pos.YOffset;
  112.                 *x = crsr->vf->Pos.XOffset;
  113.                 *x += (crsr->after) ? crsr->vf->Pos.Width + CURSORWIDTH : -2*CURSORWIDTH;
  114.         }
  115.         else {
  116.                 *x = OffX + FontX;                      /* As in CalcAllPos() */
  117.                 *y = OffY + (FontY >> 1);       /* As in CalcAllPos() */
  118.         }
  119. }
  120.  
  121. static int PreviousPosition(struct Layout *Lay, Cursor *crsr)
  122. {
  123.         /* Position cursor one step to the left (maybe up) */
  124.         /* Return FALSE if this is not possible */
  125.         struct VisFldInfo *vf;
  126.  
  127.         if (!crsr->vf) return FALSE;    /* No gadgets at all */
  128.  
  129.         if (crsr->after) {
  130.                 crsr->after = FALSE;
  131.                 return TRUE;
  132.         }
  133.         else if (vf = PrevVisFldInfo(Lay, crsr->vf)) {
  134.                 crsr->vf = vf;
  135.                 crsr->after = TRUE;
  136.                 return TRUE;
  137.         }
  138.         return FALSE;
  139. }
  140.  
  141. static int NextPosition(struct Layout *Lay, Cursor *crsr)
  142. {
  143.         /* Position cursor one step to the right (maybe down) */
  144.         /* Return FALSE if this is not possible */
  145.  
  146.         if (!crsr->vf) return FALSE;    /* No gadgets at all */
  147.  
  148.         if (!crsr->after) {
  149.                 crsr->after = TRUE;
  150.                 return TRUE;
  151.         }
  152.         else if (crsr->vf->Next) {
  153.                 crsr->vf = crsr->vf->Next;
  154.                 crsr->after = FALSE;
  155.                 return TRUE;
  156.  
  157.         }
  158.         return FALSE;
  159. }
  160.  
  161.  
  162. static void DisplayCursor(struct RastPort *rp, WORD x, WORD y)
  163. {
  164.         /* Draws a cursor in complement colour at given position */
  165.         /* Deletes cursor at old position automatically */
  166.         /* Specify a negative coordinate in either x or y to remove cursor */
  167.         /* DisplayCursor assumes a locked cursorheight */
  168.  
  169.         static WORD oldx = -1, oldy = -1;
  170.  
  171.         SetDrMd(rp, COMPLEMENT);
  172.  
  173.         if (oldx>=0 && oldy>=0)
  174.                 RectFill(rp, oldx, oldy, oldx+CURSORWIDTH-1, oldy+FontY+STRGADFRAMESHEIGHT-1);
  175.  
  176.         if (x>=0 && y>=0)
  177.                 RectFill(rp, x, y, x+CURSORWIDTH-1, y+FontY+STRGADFRAMESHEIGHT-1);
  178.         oldx = x;
  179.         oldy = y;
  180. }
  181.  
  182. static void Rubberband(struct RastPort *rp, WORD left, WORD top, WORD width, WORD height, char handle)
  183. {
  184.         /* Draws a border rectangle in complement colour. Adds a handle square if "handle" is TRUE */
  185.         /* Deletes old rubberband automatically */
  186.         /* Specify a negative coordinate in either left or top to remove rubberband */
  187.         static WORD oldleft = -1, oldtop = -1, oldwidth=-1, oldheight=-1, oldhandle = 0;
  188.  
  189.  
  190.         SetDrMd(rp, COMPLEMENT);
  191.         left--; top--; width++; height++;
  192.  
  193.         if (oldleft>=0 && oldtop>=0) {
  194.                 Move(rp, oldleft, oldtop);
  195.                 Draw(rp, oldleft+oldwidth, oldtop);
  196.                 Draw(rp, oldleft+oldwidth, oldtop+oldheight);
  197.                 Draw(rp, oldleft, oldtop+oldheight);
  198.                 Draw(rp, oldleft, oldtop);
  199.                 if (oldhandle) { /* Draw a 3x4 square in the middle of the right border */
  200.                         RectFill(rp, oldleft+oldwidth+1, oldtop+(oldheight>>1), oldleft+oldwidth+4, oldtop+(oldheight>>1)+2);
  201.                 }
  202.         }
  203.  
  204.         if (left>=0 && top>=0) {
  205.                 Move(rp, left, top);
  206.                 Draw(rp, left+width, top);
  207.                 Draw(rp, left+width, top+height);
  208.                 Draw(rp, left, top+height);
  209.                 Draw(rp, left, top);
  210.                 if (handle) { /* Draw a 3x4 square in the middle of the right border */
  211.                         RectFill(rp, left+width+1, top+(height>>1), left+width+4, top+(height>>1)+2);
  212.                 }
  213.         }
  214.         oldleft = left; oldtop = top; oldwidth = width; oldheight = height; oldhandle = handle;
  215.  
  216. }
  217.  
  218.  
  219. void FollowMouse(struct Layout *Lay, WORD mx, WORD my)
  220. {
  221.         /* Moves the cursor to the position that is nearest to (x,y) */
  222.         Cursor nearest;
  223.         WORD x,y;
  224.         WORD nx, ny;
  225.  
  226.         if (!Crsr.vf) return;
  227.         while (PreviousPosition(Lay, &Crsr));   /* Go to the beginning */
  228.         nearest = Crsr;
  229.         GetCursorPosition(&nearest, &nx, &ny);
  230.  
  231.         while (NextPosition(Lay, &Crsr)) {
  232.                 GetCursorPosition(&Crsr, &x, &y);
  233.                 if (abs(my-y) < abs(my-ny)) {
  234.                         nearest = Crsr;
  235.                         GetCursorPosition(&nearest, &nx, &ny);
  236.                 }
  237.                 if (abs(my-y) == abs(my-ny))
  238.                         if (abs(mx-x) < abs(mx-nx)) {
  239.                                 nearest = Crsr;
  240.                                 GetCursorPosition(&nearest, &nx, &ny);
  241.                         }
  242.         }
  243.         Crsr = nearest;
  244.         DisplayCursor(Lay->Window->RPort, nx, ny);
  245. }
  246.  
  247. static struct VisFldInfo *VisFldHit(struct Layout *Lay, WORD x, WORD y)
  248. {
  249.         /* Returns the address of the VisFldInfo that is hit by (x,y) */
  250.         struct VisFldInfo *vf = NULL;
  251.         
  252.         for (vf = Lay->FirstVisFldInfo; vf; vf = vf->Next) {
  253.                 if (x >= vf->Pos.XOffset && x < vf->Pos.XOffset+vf->Pos.Width &&
  254.                          y >= vf->Pos.YOffset && y < vf->Pos.YOffset+vf->Pos.Height)
  255.